﻿/*
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at
  http://www.mozilla.org/MPL/
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the
  License.
  
  The Original Code is [maashaack framework].
  
  The Initial Developers of the Original Code are
  Zwetan Kjukov <zwetan@gmail.com> and Marc Alcaraz <ekameleon@gmail.com>.
  Portions created by the Initial Developers are Copyright (C) 2006-2014
  the Initial Developers. All Rights Reserved.
  
  Contributor(s):
  
  Alternatively, the contents of this file may be used under the terms of
  either the GNU General Public License Version 2 or later (the "GPL"), or
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  in which case the provisions of the GPL or the LGPL are applicable instead
  of those above. If you wish to allow use of your version of this file only
  under the terms of either the GPL or the LGPL, and not to allow others to
  use your version of this file under the terms of the MPL, indicate your
  decision by deleting the provisions above and replace them with the notice
  and other provisions required by the LGPL or the GPL. If you do not delete
  the provisions above, a recipient may use your version of this file under
  the terms of any one of the MPL, the GPL or the LGPL.
*/
package molecule.render.starling.textures
{
    import flash.geom.Rectangle;

    import starling.textures.Texture;

    /**
     * You can use 9-slice scaling texture to specify component-style scaling for sprites. 
     * 9-slice scaling lets you create symbols that scale appropriately for use as user interface components, as opposed to the type of scaling typically applied to graphics and design elements.
     */
    public final class Scale9Texture
    {
        /**
         * Creates a new Scale9Texture instance.
         * @param texture The texture to cut in nine regions.
         * @param scale9Grid The rectangular region that defines the nine scaling regions for the texture.
         */
        public function Scale9Texture( texture:Texture , scale9Grid:Rectangle )
        {
            _texture    = texture ;
            _scale9Grid = scale9Grid ;
            initialize();
        }
        
        /**
         * The texture for the region in the bottom center.
         */
        public function get bottomCenter():Texture
        {
            return _bottomCenter;
        }
        
        /**
         * The texture for the region in the bottom left.
         */
        public function get bottomLeft():Texture
        {
            return _bottomLeft;
        }
        
        /**
         * The texture for the region in the bottom right.
         */
        public function get bottomRight():Texture
        {
            return _bottomRight;
        }
        
        /**
         * The texture for the region in the middle center.
         */
        public function get middleCenter():Texture
        {
            return _middleCenter;
        }
        
        /**
         * The texture for the region in the middle left.
         */
        public function get middleLeft():Texture
        {
            return _middleLeft;
        }
        
        /**
         * The texture for the region in the middle right.
         */
        public function get middleRight():Texture
        {
            return _middleRight;
        }
        
        /**
         * The grid representing the nine sub-regions of the texture.
         */
        public function get scale9Grid():Rectangle
        {
            return _scale9Grid;
        }
        
        /**
         * The original texture.
         */
        public function get texture():Texture
        {
            return _texture;
        }
        
        /**
         * The texture for the region in the top center.
         */
        public function get topCenter():Texture
        {
            return _topCenter;
        }
        
        /**
         * The texture for the region in the top Left.
         */
        public function get topLeft():Texture
        {
            return _topLeft;
        }
        
        /**
         * The texture for the region in the top right.
         */
        public function get topRight():Texture
        {
            return _topRight;
        }
        
        /**
         * @private
         */
        private var _bottomCenter:Texture ;
        
        /**
         * @private
         */
        private var _bottomRight:Texture;
        
        /**
         * @private
         */
        private var _bottomLeft:Texture;
        
        /**
         * @private
         */
        private var _middleCenter:Texture;
        
        /**
         * @private
         */
        private var _middleLeft:Texture;
        
        /**
         * @private
         */
        private var _middleRight:Texture;
        
        /**
         * @private
         */
        private var _scale9Grid:Rectangle;
        
        /**
         * @private
         */
        private var _texture:Texture;
        
        /**
         * @private
         */
        private var _topCenter:Texture;
        
        /**
         * @private
         */
        private var _topLeft:Texture;
        
        /**
         * @private
         */
        private var _topRight:Texture;
        
        /**
         * @private
         */
        private function initialize():void
        {
            const textureFrame:Rectangle = _texture.frame;
            const leftWidth:Number       = _scale9Grid.x;
            const centerWidth:Number     = _scale9Grid.width;
            const rightWidth:Number      = textureFrame.width - _scale9Grid.width - _scale9Grid.x;
            const topHeight:Number       = _scale9Grid.y;
            const middleHeight:Number    = _scale9Grid.height;
            const bottomHeight:Number    = textureFrame.height - _scale9Grid.height - _scale9Grid.y;
            
            const regionLeftWidth:Number    = leftWidth + textureFrame.x;
            const regionTopHeight:Number    = topHeight + textureFrame.y;
            const regionRightWidth:Number   = rightWidth - (textureFrame.width - _texture.width) - textureFrame.x;
            const regionBottomHeight:Number = bottomHeight - (textureFrame.height - _texture.height) - textureFrame.y;
            
            const hasLeftFrame:Boolean  = regionLeftWidth != leftWidth ;
            const hasTopFrame:Boolean    = regionTopHeight != topHeight ;
            const hasRightFrame:Boolean  = regionRightWidth != rightWidth ;
            const hasBottomFrame:Boolean = regionBottomHeight != bottomHeight ;
            
            const topLeftRegion:Rectangle = new Rectangle(0, 0, regionLeftWidth, regionTopHeight);
            const topLeftFrame:Rectangle = (hasLeftFrame || hasTopFrame) ? new Rectangle(textureFrame.x, textureFrame.y, leftWidth, topHeight) : null;
            _topLeft = Texture.fromTexture(_texture, topLeftRegion, topLeftFrame);
            
            const topCenterRegion:Rectangle = new Rectangle(regionLeftWidth, 0, centerWidth, regionTopHeight);
            const topCenterFrame:Rectangle = hasTopFrame ? new Rectangle(0, textureFrame.y, centerWidth, topHeight) : null;
            _topCenter = Texture.fromTexture(_texture, topCenterRegion, topCenterFrame);
            
            const topRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, 0, regionRightWidth, regionTopHeight);
            const topRightFrame:Rectangle = (hasTopFrame || hasRightFrame) ? new Rectangle(0, textureFrame.y, rightWidth, topHeight) : null;
            _topRight = Texture.fromTexture(_texture, topRightRegion, topRightFrame);
            
            const middleLeftRegion:Rectangle = new Rectangle(0, regionTopHeight, regionLeftWidth, middleHeight);
            const middleLeftFrame:Rectangle = hasLeftFrame ? new Rectangle(textureFrame.x, 0, leftWidth, middleHeight) : null;
            _middleLeft = Texture.fromTexture(_texture, middleLeftRegion, middleLeftFrame);
            
            const middleCenterRegion:Rectangle = new Rectangle(regionLeftWidth, regionTopHeight, centerWidth, middleHeight);
            _middleCenter = Texture.fromTexture(_texture, middleCenterRegion);
            
            const middleRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, regionTopHeight, regionRightWidth, middleHeight);
            const middleRightFrame:Rectangle = hasRightFrame ? new Rectangle(0, 0, rightWidth, middleHeight) : null;
            _middleRight = Texture.fromTexture(_texture, middleRightRegion, middleRightFrame);
            
            const bottomLeftRegion:Rectangle = new Rectangle(0, regionTopHeight + middleHeight, regionLeftWidth, regionBottomHeight);
            const bottomLeftFrame:Rectangle = (hasLeftFrame || hasBottomFrame) ? new Rectangle(textureFrame.x, 0, leftWidth, bottomHeight) : null;
            _bottomLeft = Texture.fromTexture(_texture, bottomLeftRegion, bottomLeftFrame);
            
            const bottomCenterRegion:Rectangle = new Rectangle(regionLeftWidth, regionTopHeight + middleHeight, centerWidth, regionBottomHeight);
            const bottomCenterFrame:Rectangle = hasBottomFrame ? new Rectangle(0, 0, centerWidth, bottomHeight) : null;
            _bottomCenter = Texture.fromTexture(_texture, bottomCenterRegion, bottomCenterFrame);
            
            const bottomRightRegion:Rectangle = new Rectangle(regionLeftWidth + centerWidth, regionTopHeight + middleHeight, regionRightWidth, regionBottomHeight);
            const bottomRightFrame:Rectangle = (hasBottomFrame || hasRightFrame) ? new Rectangle(0, 0, rightWidth, bottomHeight) : null;
            _bottomRight = Texture.fromTexture(_texture, bottomRightRegion, bottomRightFrame);
        }
    }
}
